package com.culture.config.core;

import java.util.Map;
import java.util.Objects;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@Qualifier("appContextUtil")
public class AppContextUtil implements ApplicationContextAware {
	@Autowired
	private WebApplicationContext webApplicationContext;
	private static ApplicationContext appInstance = null;
	
	@PostConstruct
    public void initApplicationContext(){
		if(this.webApplicationContext == null) {
			return;
		}		
        RequestMappingHandlerMapping mapping = this.webApplicationContext.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo,HandlerMethod> urlHandlerMap = mapping.getHandlerMethods();   
        urlHandlerMap.forEach((k,v)->{
        	 String controllerName = v.getBeanType().getName();
        	 String method = v.getMethod().getName();        
        	 Set<String> patterns = k.getPatternsCondition().getPatterns();
        	 patterns.forEach(e->{
        		 log.info("Mapped [{},{}::{}]", e, controllerName, method);
        	 });
        });        
    }    

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    	AppContextUtil.saveApplicationContext(applicationContext);
    }
    
    @SuppressWarnings("unchecked")
	public static <T> T getBean(String name) throws BeansException {
        if (AppContextUtil.appInstance == null){
            return null;
        }
        Object beanObj = AppContextUtil.appInstance.getBean(name);        
        if(Objects.isNull(beanObj)) {
        	return null;
        }       
        return (T)beanObj;
    }
    
    private static void saveApplicationContext(ApplicationContext applicationContext){
        AppContextUtil.appInstance = applicationContext;
    }
}
